package kit.docker.validator;

import kit.docker.datetime.DateKit;
import com.jfinal.kit.StrKit;
import org.quartz.impl.triggers.CronTriggerImpl;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符校验工具类
 */
public class ValidatorKit {

    private static boolean isBlank(String str) {
        return StrKit.isBlank(str);
    }

    // ==================================常规性正则==============================================
    /**
     * 中文、字母大小写、数字
     */
    public static final Pattern pattern_cln = Pattern.compile("^[A-Za-z0-9\\u4e00-\\u9fa5]+$");

    /**
     * 英文字母大小写、数字
     */
    public static final Pattern pattern_ln = Pattern.compile("^[A-Za-z0-9]+$");

    /**
     * 中文
     */
    public static final Pattern pattern_chinese = Pattern.compile("^[\\u4e00-\\u9fa5]+$");

    /**
     * 字母
     */
    public static final Pattern pattern_letter = Pattern.compile("^[A-Za-z]+$");

    /**
     * 字母 大写
     */
    public static final Pattern pattern_letter_upper = Pattern.compile("^[A-Za-z]+$");

    /**
     * 字母 小写
     */
    public static final Pattern pattern_letter_lower = Pattern.compile("^[A-Za-z]+$");

    /**
     * 数字
     */
    public static final Pattern pattern_number = Pattern.compile("^[0-9]+$");

    /**
     * 组合1：英文字母大小写、数字、下划线
     */
    public static final Pattern pattern_group_1 = Pattern.compile("^[A-Za-z0-9_]+$");

    /**
     * 组合2：英文字母大小写、数字、中文、下划线
     */
    public static final Pattern pattern_group_2 = Pattern.compile("^[A-Za-z0-9\\u4e00-\\u9fa5_]+$");


    // ==================================特定用正则==============================================

    /**
     * 手机号
     */
    public static final Pattern pattern_mobile = Pattern.compile("^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$");

    /**
     * IP地址
     */
    public static final Pattern pattern_ip = Pattern.compile("^((25[0-5]|2[0-4]\\\\d|[1]{1}\\\\d{1}\\\\d{1}|[1-9]{1}\\\\d{1}|\\\\d{1})($|(?!\\\\.$)\\\\.)){4}$");

    /**
     * 端口号
     */
    public static final Pattern pattern_port = Pattern.compile("^([0-9]|[1-9]/d|[1-9]/d{2}|[1-9]/d{3}|[1-5]/d{4}|6[0-4]/d{3}|65[0-4]/d{2}|655[0-2]/d|6553[0-5])$");

    /**
     * 邮件
     */
    public static final Pattern pattern_email = Pattern.compile("\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b");


    // ==================================自定义规则正则==============================================

    /**
     * 32位 字母+数字组合 uuid
     */
    public final static Pattern pattern_uuid32 = Pattern.compile("[a-zA-Z0-9]{32,32}");

    /**
     * 32位 字母大写+数字组合 uuid
     */
    public final static Pattern pattern_uuid32_upper = Pattern.compile("[A-Z0-9]{32,32}");

    /**
     * 32位 字母小写+数字组合 uuid
     */
    public final static Pattern pattern_uuid32_lower = Pattern.compile("[a-z0-9]{32,32}");

    /**
     * 32位 uuid 逗号分隔组合
     * Pattern.compile("(^[a-z0-9]{32},)*[a-z0-9]{32}$");
     * Pattern.compile("^(?!.*(^|,)([^,]*),(\\2|.*,\\2)(,|$))[^,]+(,[^,]+)+$");
     */
    public final static Pattern pattern_uuid32s = Pattern.compile("^(?!.*(^|,)([^,]*),(\\2|.*,\\2)(,|$))[^,]{32}(,[^,]{32})+$");

    public final static Pattern pattern_class_name = Pattern.compile("^([0-9]{1,2})(\\-)([0-9]{2})$");

    public final static Pattern pattern_dorm_name = Pattern.compile("^([1-9])([0-9]{0,2})(\\-)([0-9]{4})$");

    public final static Pattern pattern_package = Pattern.compile("^(\\w+\\.)(\\w+\\.)*\\w+$");

    // ==================================校验方法==============================================

    public static boolean validateRegExp(Pattern pattern, String str) {
        if (StrKit.isBlank(str)) {
            return false;
        }
        return pattern.matcher(str).matches();
    }

    // ========================================================================================

    public static boolean validateString(String str) {
        return !isBlank(str);
    }

    public static boolean validateString(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateString(str);
    }

    public static boolean validateString(String str, int minLen, int maxLen) {
        if (isBlank(str)) return false;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return true;
    }

    public static boolean validateString(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateString(str, minLen, maxLen);
    }

    public static boolean validateString(String str, int limit) {
        return validateString(str, limit, limit);
    }

    public static boolean validateString(String str, int limit, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateString(str, limit);
    }


    // ----------------------------------------------------------------------------------------

    public static boolean validateCLN(String str) {
        return validateCLN(str, false);
    }

    public static boolean validateCLN(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_cln, str);
    }

    public static boolean validateCLN(String str, int minLen, int maxLen) {
        return validateCLN(str, minLen, maxLen, false);
    }

    public static boolean validateCLN(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateCLN(str);
    }

    public static boolean validateCLN(String str, int fixLen) {
        return validateCLN(str, fixLen, false);
    }

    public static boolean validateCLN(String str, int fixLen, boolean allowNull) {
        return validateCLN(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateLN(String str) {
        return validateLN(str, false);
    }

    public static boolean validateLN(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_ln, str);
    }

    public static boolean validateLN(String str, int minLen, int maxLen) {
        return validateLN(str, minLen, maxLen, false);
    }

    public static boolean validateLN(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateLN(str);
    }

    public static boolean validateLN(String str, int fixLen) {
        return validateLN(str, fixLen, false);
    }

    public static boolean validateLN(String str, int fixLen, boolean allowNull) {
        return validateLN(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateChinese(String str) {
        return validateChinese(str, false);
    }

    public static boolean validateChinese(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_chinese, str);
    }

    public static boolean validateChinese(String str, int minLen, int maxLen) {
        return validateChinese(str, minLen, maxLen, false);
    }

    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    public static boolean validateChinese(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (!allowNull && isBlank(str)) return false;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateChinese(str);
    }

    public static boolean validateChinese(String str, int fixLen) {
        return validateChinese(str, fixLen, false);
    }

    public static boolean validateChinese(String str, int fixLen, boolean allowNull) {
        return validateChinese(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateLetter(String str) {
        return validateLetter(str, false);
    }

    public static boolean validateLetter(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_letter, str);
    }

    public static boolean validateLetter(String str, int minLen, int maxLen) {
        return validateLetter(str, minLen, maxLen, false);
    }

    public static boolean validateLetter(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateLetter(str);
    }

    public static boolean validateLetter(String str, int fixLen) {
        return validateLetter(str, fixLen, false);
    }

    public static boolean validateLetter(String str, int fixLen, boolean allowNull) {
        return validateLetter(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateLetterUpper(String str) {
        return validateLetterUpper(str, false);
    }

    public static boolean validateLetterUpper(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_letter_upper, str);
    }

    public static boolean validateLetterUpper(String str, int minLen, int maxLen) {
        return validateLetterUpper(str, minLen, maxLen, false);
    }

    public static boolean validateLetterUpper(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateLetterUpper(str);
    }

    public static boolean validateLetterUpper(String str, int fixLen) {
        return validateLetterUpper(str, fixLen, false);
    }

    public static boolean validateLetterUpper(String str, int fixLen, boolean allowNull) {
        return validateLetterUpper(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateLetterLower(String str) {
        return validateLetterLower(str, false);
    }

    public static boolean validateLetterLower(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_letter_lower, str);
    }

    public static boolean validateLetterLower(String str, int minLen, int maxLen) {
        return validateLetterLower(str, minLen, maxLen, false);
    }

    public static boolean validateLetterLower(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateLetterLower(str);
    }

    public static boolean validateLetterLower(String str, int fixLen) {
        return validateLetterLower(str, fixLen, false);
    }

    public static boolean validateLetterLower(String str, int fixLen, boolean allowNull) {
        return validateLetterLower(str, fixLen, fixLen, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateNumber(String str) {
        return validateNumber(str, false);
    }

    public static boolean validateNumber(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_number, str);
    }

    public static boolean validateNumber(String str, int minLen, int maxLen) {
        return validateNumber(str, minLen, maxLen, false);
    }

    public static boolean validateNumber(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateNumber(str);
    }

    public static boolean validateNumber(String str, long minLen, long maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateNumber(str);
    }

    public static boolean validateNumber(String str, int fixLen) {
        return validateNumber(str, fixLen, false);
    }

    public static boolean validateNumber(String str, int fixLen, boolean allowNull) {
        if (!allowNull && isBlank(str)) return false;
        if (str.length() != fixLen) {
            return false;
        }
        return validateNumber(str, allowNull);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateMobile(String str) {
        return validateMobile(str, false);
    }

    public static boolean validateMobile(String str, boolean allowNull) {
        if (isBlank(str) && allowNull) return true;
        return validateRegExp(pattern_mobile, str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateIP(String str) {
        return validateIP(str, false);
    }

    public static boolean validateIP(String str, boolean allowNull) {
        if (isBlank(str) && allowNull) return true;
        return validateRegExp(pattern_ip, str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validatePort(String str) {
        return validatePort(str, false);
    }

    public static boolean validatePort(String str, boolean allowNull) {
        if (isBlank(str) && allowNull) return true;
        return validateRegExp(pattern_port, str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateEmail(String str) {
        return validateEmail(str, false);
    }

    public static boolean validateEmail(String str, boolean allowNull) {
        if (isBlank(str) && allowNull) return true;
        return validateRegExp(pattern_email, str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateUUID32(String uuid32) {
        return validateUUID32(uuid32, false);
    }

    public static boolean validateUUID32(String uuid32, boolean allowNull) {
        if (allowNull && isBlank(uuid32)) return true;
        return validateRegExp(pattern_uuid32_lower, uuid32);
    }

    public static boolean validateUUID32s(String uuid32s) {
        return validateUUID32s(uuid32s, false);
    }

    public static boolean validateUUID32s(String uuid32s, boolean allowNull) {
        if (allowNull && isBlank(uuid32s)) return true;
        if (!allowNull && isBlank(uuid32s)) return false;
        if (uuid32s.length() == 32) {
            return validateUUID32(uuid32s);
        } else {
            return validateRegExp(pattern_uuid32s, uuid32s);
        }

    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateDate(String str) {
        return validateDate(str, false);
    }

    public static boolean validateDate(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return DateKit.isDate(str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateGroup1(String str) {
        return validateGroup1(str, false);
    }

    public static boolean validateGroup1(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_group_1, str);
    }

    public static boolean validateGroup1(String str, int minLen, int maxLen) {
        return validateGroup1(str, minLen, maxLen, false);
    }

    public static boolean validateGroup1(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateRegExp(pattern_group_1, str);
    }

    public static boolean validateGroup1(String str, int fixLen) {
        return validateGroup1(str, fixLen, false);
    }

    public static boolean validateGroup1(String str, int fixLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() != fixLen) {
            return false;
        }
        return validateRegExp(pattern_group_1, str);
    }

    // ----------------------------------------------------------------------------------------

    public static boolean validateGroup2(String str) {
        return validateGroup2(str, false);
    }

    public static boolean validateGroup2(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_group_2, str);
    }

    public static boolean validateGroup2(String str, int minLen, int maxLen) {
        return validateGroup2(str, minLen, maxLen, false);
    }

    public static boolean validateGroup2(String str, int minLen, int maxLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() < minLen || str.length() > maxLen) {
            return false;
        }
        return validateRegExp(pattern_group_2, str);
    }

    public static boolean validateGroup2(String str, int fixLen) {
        return validateGroup2(str, fixLen, false);
    }

    public static boolean validateGroup2(String str, int fixLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() != fixLen) {
            return false;
        }
        return validateRegExp(pattern_group_2, str);
    }

    // ----------------------------------------------------------------------------------------
    public static boolean validateInteger(String num) {
        if (isBlank(num)) {
            return false;
        }
        try {
            Integer.parseInt(num);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateInteger(String num, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateInteger(num);
    }

    public static boolean validateInteger(String num, int minLen, int maxLen) {
        if (isBlank(num)) {
            return false;
        }
        try {
            int temp = Integer.parseInt(num);
            if (temp < minLen || temp > maxLen) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateInteger(String num, int minLen, int maxLen, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateInteger(num, minLen, maxLen);
    }

    public static boolean validateLong(String num) {
        if (isBlank(num)) {
            return false;
        }
        try {
            Long.parseLong(num);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateLong(String num, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateLong(num);
    }

    public static boolean validateLong(String num, Long minLen, Long maxLen) {
        if (isBlank(num)) {
            return false;
        }
        try {
            Long temp = Long.parseLong(num.trim());
            if (temp < minLen || temp > maxLen) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateLong(String num, Long minLen, Long maxLen, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateLong(num, minLen, maxLen);
    }


    // ----------------------------------------------------------------------------------------
    public static boolean validateDouble(String num) {
        if (isBlank(num)) {
            return false;
        }
        try {
            Double.parseDouble(num.trim());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateDouble(String num, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateDouble(num);
    }

    public static boolean validateDouble(String num, double minLen, double maxLen) {
        if (isBlank(num)) {
            return false;
        }
        try {
            double temp = Double.parseDouble(num.trim());
            if (temp < minLen || temp > maxLen) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean validateDouble(String num, double minLen, double maxLen, boolean allowNull) {
        if (isBlank(num) && allowNull) {
            return true;
        }
        return validateDouble(num, minLen, maxLen);
    }

    // ----------------------------------------------------------------------------------------
    public static boolean validateClassName(String str) {
        return validateClassName(str, false);
    }

    public static boolean validateClassName(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_class_name, str);
    }

    public static boolean validateDormName(String str) {
        return validateDromName(str, false);
    }

    public static boolean validateDromName(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        return validateRegExp(pattern_dorm_name, str);
    }

    public static boolean validatePackage(String str, int minLen, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (str.length() != minLen) return false;
        return validateRegExp(pattern_package, str);
    }

    //验证定时器时间表达式
    public static boolean validateCron(String str, boolean allowNull) {
        if (allowNull && isBlank(str)) return true;
        if (!allowNull && isBlank(str)) return false;
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            trigger.setCronExpression(str);
            Date date = trigger.computeFirstFireTime(null);
            return date != null && date.after(new Date());
        } catch (Exception e) {
            return false;
        }
    }

}